package com.tengju.user.application.club;

import com.google.common.collect.Lists;
import com.tengju.user.application.archives.dto.PageQueryDTO;
import com.tengju.user.application.club.dto.AddZoneForm;
import com.tengju.user.application.club.dto.EditZoneForm;
import com.tengju.user.application.club.dto.UserZoneRelationForm;
import com.tengju.user.application.shared.ApplicationException;
import com.tengju.user.application.shared.ApplicationExceptionCode;
import com.tengju.user.domain.model.club.*;
import com.tengju.user.domain.model.user.*;
import com.tengju.user.domain.service.HuaweiObsService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ZoneService {

    @Autowired
    HuaweiObsService huaweiObsService;
    @Autowired
    ZoneRepository zoneRepository;

    @Autowired
    ClubZoneRelationRepository clubZoneRelationRepository;

    @Autowired
    UserInfoRepository userInfoRepository;

    @Autowired
    UserZoneMemberRepository userZoneMemberRepository;


    public List<Zone> queryByPage(PageQueryDTO pageQueryDTO) {
        Integer pageSize = pageQueryDTO.getPageSize();
        Integer pageIndex = pageQueryDTO.getPageIndex();
        Integer offset = (pageIndex - 1) * pageSize;
        pageQueryDTO.setOffset(offset);
        return zoneRepository.findByPage(offset,pageSize);
    }


    public Boolean addZone(AddZoneForm addZoneForm, Staff staff) {
        Zone exist = zoneRepository.findByName(addZoneForm.getZoneName());
        if (exist != null) {
            throw ApplicationException.error(ApplicationExceptionCode.ZONE_NAME_EXIST);
        }
        Zone zone = ZoneFactory
                .create(addZoneForm.getZoneName(), addZoneForm.getZoneHeadImgUrl(), staff);
        return zoneRepository.addZone(zone);
    }

    public Boolean editZone(EditZoneForm editZoneForm, Staff staff) {

        Zone zone = zoneRepository.findById(editZoneForm.getZoneId());
        if (zone == null) {
            throw ApplicationException.error(ApplicationExceptionCode.INVALID_DATA,"该战区不存在");
        }
        if (!editZoneForm.getZoneName().equals(zone.getName())) {
            Zone exist = zoneRepository.findByName(editZoneForm.getZoneName());
            if (exist != null) {
                throw ApplicationException.error(ApplicationExceptionCode.ZONE_NAME_EXIST);
            }
        }

        zone.editZoneInfo(editZoneForm.getZoneName(),editZoneForm.getZoneHeadImgUrl(),staff.getName());

        return zoneRepository.editZone(zone);
    }

    public Boolean delZone(ZoneId zoneId) {

        List<ClubZoneRelation> clubZoneRelationList = clubZoneRelationRepository.findByZoneId(zoneId);
        if (!CollectionUtils.isEmpty(clubZoneRelationList)) {
            throw ApplicationException.error(ApplicationExceptionCode.ZONE_EXIST_CLUB);
        }
        return zoneRepository.delZone(zoneId);
    }

    @Transactional(rollbackFor = Throwable.class)
    public void saveUserZoneMember(UserZoneRelationForm userZoneRelationForm) {

        // 支持任意非数字分割组装secId
        List<UserIdCode> secIdList = Lists.newArrayList();
        if (StringUtils.isNotEmpty(userZoneRelationForm.getSecIds())) {
            secIdList = Arrays.stream(userZoneRelationForm.getSecIds().split("\\D"))
                    .filter(StringUtils::isNotEmpty)
                    .map(Long::parseLong)
                    .map(UserIdCode::new)
                    .distinct().collect(Collectors.toList());

        }


        // 校验SEC EEC 是否存在
        List<UserInfo> userInfoList = userInfoRepository.batchGetUserInfo(secIdList);
        userInfoList = userInfoList.stream()
                .filter(v -> (StarLevelEnum.SEC.getCode().equals(v.getStarLevel())
                        || StarLevelEnum.EEC.getCode().equals(v.getStarLevel())))
                .collect(Collectors.toList());

        List<UserIdCode> userInfoIdCodeList = userInfoList.stream()
                .map(UserInfo::getUserIdCode)
                .collect(Collectors.toList());

        if (secIdList.size() != userInfoList.size()) {
            // 记录不存在的SecIDCode
            String notExitsStr = secIdList.stream().filter(v -> !userInfoIdCodeList.contains(v))
                    .map(UserIdCode::getValue)
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));

            throw ApplicationException.error(ApplicationExceptionCode.GENSEC_NOT_EXIST,notExitsStr);

        }

        // 删除所有zoneId下的所有sec
        userZoneMemberRepository.deleteByZoneId(new ZoneId(userZoneRelationForm.getZoneId()));

        // 校验同一个idCode是否被其他战区绑定
        List<UserZoneMemberInfo> validInfoList = userZoneMemberRepository.selectByUserIdCode(userInfoIdCodeList);
        if (!CollectionUtils.isEmpty(validInfoList)) {
            // 记录已被其它战区绑定的SecIDCode
            String existsUserIdCodeStr = validInfoList.stream()
                    .map(UserZoneMemberInfo::getUserIdCode)
                    .map(UserIdCode::getValue)
                    .map(String::valueOf)
                    .collect(Collectors.joining(","));
            throw ApplicationException.error(ApplicationExceptionCode.OTHER_USER_ZONE_MEMBER_EXIST,existsUserIdCodeStr);
        }


        List<UserZoneMemberInfo> userZoneMemberInfoList = Lists.newArrayList();
        for (UserInfo userInfo : userInfoList) {
            UserZoneMemberInfo userZoneMemberInfo = new UserZoneMemberInfo(null,
                    new ZoneId(userZoneRelationForm.getZoneId()),
                    userInfo.getUserIdCode(),
                    userInfo.getUserId());

            userZoneMemberInfoList.add(userZoneMemberInfo);

        }

        // 保存战区下的所有所有sec关联信息
        userZoneMemberRepository.batchInsert(userZoneMemberInfoList);



    }
}
